package com.it.water.service.impl;

import cn.hutool.crypto.SecureUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.it.water.controller.HttpController.dto.LoginDTO;
import com.it.water.controller.HttpController.request.LoginRequest;
import com.it.water.entity.User;
import com.it.water.exception.ServiceException;
import com.it.water.mapper.UserMapper;
import com.it.water.utils.AssertUtil;
import com.it.water.utils.TokenUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;


/**
 * 用户服务实现类，实现IUserService接口
 *
 * @author <a href="mailto:2038322151@qq.com">Miraitowa_zcx</a>
 * @author HelloWorld505
 * @version 1.0
 * @since 2024-03-17
 */
@Service
public class UserService extends ServiceImpl<UserMapper, User> implements com.it.water.service.IUserService {

    private final UserMapper userMapper;

    /**
     * 构造方法，注入用户Mapper
     *
     * @param userMapper 用户数据访问对象
     */
    @Autowired
    public UserService(UserMapper userMapper) {
        this.userMapper = userMapper;
    }

    @Resource
    private SendVerifyCodeService sendVerifyCodeService;

    /**
     * 密码盐值
     */
    private static final String PASS_SALT = "Miraitowa";

    /**
     * 用户注册
     *
     * @param user 用户对象
     * @return 登录信息
     */
    public LoginDTO register(User user) {
        User register = userMapper.getByUsername(user.getUsername());
        if (register != null) {
            throw new ServiceException("用户名已存在");
        } else {
            //校验手机号是否已注册
            AssertUtil.isTrue(checkPhoneIsRegistered(user.getPhone()), "手机号已注册");
            // 从redis中获取验证码
            String code = sendVerifyCodeService.getCodeByPhone();
            // 验证是否过期
            AssertUtil.isNotEmpty(code, "验证码已过期，请重新发送");
            // 验证码一致性校验
            if (!user.getVerifyCode().equals(code)) {
                throw new ServiceException("验证码不一致，请重新输入");
            }
            user.setPassword(securePass(user.getPassword()));
            userMapper.save(user);
            LoginDTO loginDTO = new LoginDTO();
            BeanUtils.copyProperties(user, loginDTO);
            return loginDTO;
        }
    }

    /**
     * 用户登录
     *
     * @param request 登录请求对象
     * @return 登录信息
     */
    public LoginDTO login(LoginRequest request) {
        User user;
        try {
            user = userMapper.getByUsername(request.getUsername());
        } catch (Exception e) {
            log.error("用户登录异常", e);
            throw new ServiceException("用户登录异常");
        }
        if (user == null) {
            throw new ServiceException("用户名或密码错误");
        }
        // 判断密码是否合法
        String securePass = securePass(request.getPassword());
        if (!securePass.equals(user.getPassword())) {
            throw new ServiceException("用户名或密码错误");
        }

        LoginDTO loginDTO = new LoginDTO();
        BeanUtils.copyProperties(user, loginDTO);

        // 生成token
        String token = TokenUtils.genToken(String.valueOf(user.getId()), user.getPassword());
        loginDTO.setToken(token);
        return loginDTO;
    }

    /**
     * 校验手机号是否已注册
     */
    public Boolean checkPhoneIsRegistered(String phone) {
        AssertUtil.isNotEmpty(phone, "手机号不能为空");
        User user = userMapper.getByPhone(phone);
        return user != null;
    }

    /**
     * 密码加密解密
     *
     * @param password 密码
     * @return 密码加密结果
     */
    private String securePass(String password) {
        return SecureUtil.md5(password + PASS_SALT);
    }
}
